package com.yzl.frelink.service.analyze;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Component;

import com.yzl.frelink.entities.Fretish;
import com.yzl.frelink.entities.chart.StateTreeNode;
import com.yzl.frelink.entities.component.Chart;
import com.yzl.frelink.entities.dep.Demap;


@Component
public class RegulationAnalyzer {
    // preBool - param & state -> state: en: param
    // preBool - state
    // in - param
    // in - param & state -> inner state
    // in - state
    private void resolveRegulation(StateTreeNode current, Chart chart, Demap demap, Fretish req) {
        String[] resItems = req.getResList();
        if (current.getType() == StateTreeNode.NORMAL && req.checkPreBool()) {
            if (resItems.length > 1) {
                for (String item : resItems) {
                item = item.replace("enter_", "").trim();
                    if (demap.getModes().contains(item)) {
                        if (req.getTimingType() == null || req.getTimingType().isEmpty()) {
                            // timing == null
                            System.out.println("Not supported: EVENTUALLY");
                        } else if (req.getTimingType().equals("immediately")) {
                            // timing == immediately
                            chart.getState(item).addEntryAction(req.resolveResWithoutState());
                        } else {
                            System.out.println("Warning: requirement " + req.getReqid() + " has unsupported timing: " + req.getTimingType());
                        }
                        break;
                    }
                }
            }
        } else {
            StringBuilder entry = new StringBuilder();
            StringBuilder during = new StringBuilder();
            StringBuilder exit = new StringBuilder();

            if (req.getTimingType() == null || req.getTimingType().isEmpty()) {
                // timing == null
                System.out.println("Not supported: EVENTUALLY");
            } else if (req.getTimingType().equals("immediately")) {
                // timing == immediately
                if (req.getCondition() != null ) {
                    entry.append("if ").append(req.resolveCond()).append("\n");
                    entry.append(req.resolveRes(true, false)).append("\n");
                    entry.append("end\n");
                } else entry.append(req.resolveRes(true, false));
            } else if (req.getTimingType().equals("always")) {
                // timing == always
                if (req.getCondition() != null ) {
                    entry.append("if ").append(req.resolveCond()).append("\n");
                    entry.append(req.resolveRes(true, false)).append("\n");
                    entry.append("end\n");
                    during.append("if ").append(req.resolveCond()).append("\n");
                    during.append(req.resolveRes(true, false)).append("\n");
                    during.append("end\n");
                } else {
                    entry.append(req.resolveRes(true, false));
                    during.append(req.resolveRes(true, false));
                }
            } else if (req.getTimingType().equals("finally")) {
                // timing == finally
                if (req.getCondition() != null ) {
                    exit.append("if ").append(req.resolveCond()).append("\n");
                    exit.append(req.resolveRes(true, false)).append("\n");
                    exit.append("end\n");
                } else exit.append(req.resolveRes(true, false));
            } else {
                System.out.println("Warning: requirement " + req.getReqid() + " has unsupported timing: " + req.getTimingType());
            }
            if (entry.length() > 0) {
                current.addEntryAction(entry.toString().trim());
            }
            if (during.length() > 0) {
                current.addDuringAction(during.toString().trim());
            }
            if (exit.length() > 0) {
                current.addExitAction(exit.toString().trim());
            }
        }
    }

    public void dealRelatedReqs(StateTreeNode current, Chart chart, Demap demap, List<Fretish> reqs) {
        if (reqs == null) return;
        // 判断是否具有非设置状态和非preBool规约
        for (Fretish req : reqs) {
            resolveRegulation(current, chart, demap, req);
        }
    }

    public Map<String, List<Fretish>> groupByMode(Fretish[] requirements) {
        Map<String, List<Fretish>> modeToReqs = new HashMap<>();
        for (Fretish req : requirements) {
            String mode = req.getScope();
            if (!modeToReqs.containsKey(mode)) {
                modeToReqs.put(mode, new ArrayList<>());
            }
            modeToReqs.get(mode).add(req);
        }
        return modeToReqs;
    }
}
